#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

#include <semaforoI.h>
#include <memoriaI.h>

#define MAX_TIME_LEER 3

void lector ();
void leer ();

int main (int argc, char *argv[]) {
  lector(argv[1], argv[2], argv[3]);

  return 0;
}

void lector (char *id_var_lectores, char *id_sem_mutex, char *id_sem_acceso) {
  int num_lectores;
  srand((int)getpid());

  // Obtiene el puntero a los semáforos usados
  // y a la variable de memoria compartida.
  int num_lectores_handle = obtener_var(id_var_lectores);
  sem_t *sem_mutex = get_sem(id_sem_mutex);
  sem_t *sem_acceso = get_sem(id_sem_acceso);  

  while (1) {
    wait_sem(sem_mutex);

    // Incrementa el número de lectores.
    num_lectores = consultar_var(num_lectores_handle);
    modificar_var(num_lectores_handle, num_lectores + 1);

    // Primer lector en desbloquear.
    // El resto pasan directamente...
    if ((num_lectores + 1) == 1) 
      wait_sem(sem_acceso);

    signal_sem(sem_mutex);

    // Sección crítica para el lector.
    leer();

    wait_sem(sem_mutex);

    // Decrementa el número de lectores.
    num_lectores = consultar_var(num_lectores_handle);
    modificar_var(num_lectores_handle, num_lectores - 1);

    // Último lector?
    if (num_lectores == 0) 
      signal_sem(sem_acceso);

    signal_sem(sem_mutex);
  }
}

void leer () {
  printf("%d leyendo...\n", getpid());
  sleep(rand() % MAX_TIME_LEER);
}
